今天用 Python+Tkinter 做一個番茄鐘:專注 N 分鐘 → 休息 M 分鐘,支援開始/暫停/重置,完成會響鈴提醒。預設 25/5 分鐘,可自行調整。
功能重點
程式碼(存成 pomodoro.py
import tkinter as tk
from tkinter import ttk, messagebox
# --- 狀態 ---
running = False
mode = "work" # "work" or "break"
remaining = 0
rounds = 0
tick_job = None
def fmt(sec: int) -> str:
m, s = divmod(max(0, sec), 60)
return f"{m:02d}:{s:02d}"
def set_mode(new_mode: str):
global mode, remaining
mode = new_mode
try:
w = int(work_min.get())
b = int(break_min.get())
if w <= 0 or b <= 0:
raise ValueError
except ValueError:
messagebox.showerror("輸入錯誤", "請填入大於 0 的整數分鐘")
return
remaining = (w if mode == "work" else b) * 60
status_var.set("專注中" if mode == "work" else "休息中")
time_var.set(fmt(remaining))
def start():
global running
if running: return
running = True
tick()
def pause():
global running, tick_job
running = False
if tick_job:
root.after_cancel(tick_job)
def reset():
global running, rounds
pause()
rounds = 0
rounds_var.set("本日完成:0 次番茄")
set_mode("work")
def tick():
global remaining, rounds, tick_job
if not running: return
remaining -= 1
time_var.set(fmt(remaining))
if remaining <= 0:
root.bell() # 提示音
if mode == "work":
rounds += 1
rounds_var.set(f"本日完成:{rounds} 次番茄")
set_mode("break")
else:
set_mode("work")
tick_job = root.after(1000, tick)
# --- 介面 ---
root = tk.Tk()
root.title("Pomodoro 番茄鐘")
main = ttk.Frame(root, padding=16); main.grid()
status_var = tk.StringVar(value="專注中")
time_var = tk.StringVar(value="25:00")
rounds_var = tk.StringVar(value="本日完成:0 次番茄")
ttk.Label(main, textvariable=status_var, font=("Segoe UI", 12)).grid(row=0, column=0, columnspan=3, pady=(0,6))
ttk.Label(main, textvariable=time_var, font=("Segoe UI", 36)).grid(row=1, column=0, columnspan=3, pady=6)
# 設定
work_min = tk.StringVar(value="25")
break_min = tk.StringVar(value="5")
ttk.Label(main, text="專注(分)").grid(row=2, column=0, sticky="e", pady=4)
ttk.Entry(main, textvariable=work_min, width=6, justify="center").grid(row=2, column=1, sticky="w")
ttk.Label(main, text="休息(分)").grid(row=3, column=0, sticky="e", pady=4)
ttk.Entry(main, textvariable=break_min, width=6, justify="center").grid(row=3, column=1, sticky="w")
btns = ttk.Frame(main); btns.grid(row=4, column=0, columnspan=3, pady=10)
ttk.Button(btns, text="開始", command=start).grid(row=0, column=0, padx=4)
ttk.Button(btns, text="暫停", command=pause).grid(row=0, column=1, padx=4)
ttk.Button(btns, text="重置", command=reset).grid(row=0, column=2, padx=4)
ttk.Label(main, textvariable=rounds_var).grid(row=5, column=0, columnspan=3)
# 初始
set_mode("work")
root.bind("<Return>", lambda e: start())
root.mainloop()
使用方式
python pomodoro.py
實作:
小提醒
想改成 50/10?介面上把「專注(分)」改 50、「休息(分)」改 10,按「重置」後再「開始」。